package com.ocom.payhandle.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ocom.common.entity.card.EntityXfAccountInfo;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.enums.MasterSlaveEnum;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payhandle.dao.IDaoAccountInfo;
import com.ocom.payhandle.mq.business.saveorder.SaveOrderProductService;
import com.ocom.payhandle.service.XfAccountInfoService;
import com.ocom.payhandle.service.XfRecordProcessService;
import com.ocom.payhandle.vo.MqSaveOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;


@Service
@Slf4j
public class XfAccountInfoServiceImpl extends ServiceImpl<IDaoAccountInfo, EntityXfAccountInfo> implements XfAccountInfoService {

    @Autowired
    private IDaoAccountInfo iDaoAccountInfo;


    @Autowired
    private XfRecordProcessService xfRecordProcessService;

	@Autowired
	SaveOrderProductService saveOrderProductService;

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    @Override
    public EntityXfAccountInfo selectAccount(Long companyId, String accountNo) {
        QueryWrapper<EntityXfAccountInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("p_id","account_state","account_recharge_money","account_subsidy_money","id","acc_type_id","account_no");
        queryWrapper.eq("com_id",companyId);
        queryWrapper.eq("account_no",accountNo);
        return iDaoAccountInfo.selectOne(queryWrapper);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    @Override
    public boolean updateAccountMoney(Long companyId, Long chargeBalance, Long subBalance, Integer id) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        boolean flag = false;
        if (chargeBalance!=null){
            flag = true;
            updateWrapper.setSql("account_recharge_money = account_recharge_money + "+chargeBalance);
        }
        if (subBalance!=null){
            flag = true;
            updateWrapper.setSql("account_subsidy_money = account_subsidy_money + "+subBalance);
        }
        updateWrapper.eq("id",id);
        if(flag){
            return this.update(updateWrapper);
        }else{
            return true;
        }

    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public boolean updateAccountMoneyTransactional(Long companyId, Long chargeBalance, Long subBalance, Integer id,EntityXfRecordProcess origOrder,EntityXfRecordProcess refundOrder) {

        int i = xfRecordProcessService.updateEntityXfRecord(companyId, origOrder);
        if (i <= 0) {
            log.info("请求方式47 T7xWs6Ih :【{}】,机器号:【{}】,入库修改的数据:【{}】,返回:【{}】", "付款码退款", "feeRefund", origOrder, "付款码退款失败");
            return false;
        }

        int j = xfRecordProcessService.updateEntityXfRecord(companyId, refundOrder);
        if (j <= 0) {
            log.info("请求方式47 eH613KG0 :【{}】,机器号:【{}】,入库修改的数据:【{}】,返回:【{}】", "付款码退款", "feeRefund", origOrder, "付款码退款失败");
            return false;
        }

        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        boolean flag = false;
        if (chargeBalance!=null){
            flag = true;
            updateWrapper.setSql("account_recharge_money = account_recharge_money + "+chargeBalance);
        }
        if (subBalance!=null){
            flag = true;
            updateWrapper.setSql("account_subsidy_money = account_subsidy_money + "+subBalance);
        }
        updateWrapper.eq("id",id);
        if(flag){
            return this.update(updateWrapper);
        }else{
            return true;
        }

    }


    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    @Override
    public EntityXfAccountInfo selectAccountPid(Long companyId, Long pId) {
        QueryWrapper<EntityXfAccountInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("p_id","account_state","account_recharge_money","account_subsidy_money","id","acc_type_id","account_no");
        queryWrapper.eq("com_id",companyId);
        queryWrapper.eq("p_id",pId);
        queryWrapper.orderByDesc("update_time");
        queryWrapper.last("limit 1");
        return iDaoAccountInfo.selectOne(queryWrapper);
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public void updateAccountTransactional(Long companyId, Integer id, EntityXfRecordProcess entityXfRecordProcess, EntityXfRecordProcess updateXfRecordProcess) {

        if (null != entityXfRecordProcess.getChargeMoney() || null != entityXfRecordProcess.getSubMoney()){
            //修改金额
            UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
            boolean flag = false;
            if (null != entityXfRecordProcess.getChargeMoney() && entityXfRecordProcess.getChargeMoney()!=0){
                flag = true;
                updateWrapper.setSql("account_recharge_money = account_recharge_money + "+ entityXfRecordProcess.getChargeMoney());
            }
            if (null != entityXfRecordProcess.getSubMoney() && entityXfRecordProcess.getSubMoney()!=0){
                flag = true;
                updateWrapper.setSql("account_subsidy_money = account_subsidy_money + "+ entityXfRecordProcess.getSubMoney());
            }
            updateWrapper.eq("id",id);
            if(flag){
                if (!this.update(updateWrapper)){
                    throw new RuntimeException("修改金额失败");
                }
            }
        }


        if (xfRecordProcessService.updateEntityXfRecord(companyId,updateXfRecordProcess)<=0){
            throw new RuntimeException("修改记录失败");
        }


		MqSaveOrderVo mqSaveOrderVo=new MqSaveOrderVo();
		mqSaveOrderVo.setComId(companyId);
		mqSaveOrderVo.setId(updateXfRecordProcess.getId());
		mqSaveOrderVo.setMachNo(entityXfRecordProcess.getDeviceNo());

		saveOrderProductService.saveOrder(JSON.toJSONString(mqSaveOrderVo));

		//改为mq
//		EntityXfRecord entityXfRecord = JSONObject.parseObject(JSON.toJSONString(entiyEntiyXfRecordProcess),EntityXfRecord.class);
//        Result result=xfRecordFeign.sveXfRecord(entityXfRecord);
//        if (result.getCode()!=200){
//            throw new RuntimeException("新增成功表失败");
//        }
    }


    @Override
	@DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
	public EntityXfAccountInfo chageUserMoney(Long companyId , Long pId ,Integer money,Integer subMoney) {
		QueryWrapper<EntityXfAccountInfo> queryWrapper= new QueryWrapper<>();
		queryWrapper.eq("com_id", companyId );
		queryWrapper.eq("p_id",pId);
		queryWrapper.last(" for update");
		EntityXfAccountInfo entityXfAccountInfo = this.getOne(queryWrapper);
		if(entityXfAccountInfo == null){
			throw new RuntimeException("充值账户不存在");
		}
		UpdateWrapper<EntityXfAccountInfo> updateWrapper= new UpdateWrapper<>();
		updateWrapper.eq("com_id", companyId );
		updateWrapper.eq("p_id",pId);
		updateWrapper.setSql("account_recharge_money = account_recharge_money + "+money);
		updateWrapper.setSql("account_subsidy_money = account_subsidy_money + "+subMoney);
		Boolean b = this.update(updateWrapper);
		if(!b){
			throw new RuntimeException("充值失败");
		}
		EntityXfAccountInfo entityXfAccountInfo1 = this.getOne(queryWrapper);
		return entityXfAccountInfo1;
	}

    //修改后余额不能为负数
    @Override
    @DataSourceAspect(type= DataSourceEnum.PART_DB,isMaster = MasterSlaveEnum.MASTER)
    public EntityXfAccountInfo changeUserMoney2(Long companyId , Long pId ,Integer money,Integer subMoney) {
        QueryWrapper<EntityXfAccountInfo> queryWrapper= new QueryWrapper<>();
        queryWrapper.eq("com_id", companyId );
        queryWrapper.eq("p_id",pId);
        queryWrapper.last(" for update");
        EntityXfAccountInfo entityXfAccountInfo = this.getOne(queryWrapper);
        if(entityXfAccountInfo == null){
            throw new RuntimeException("充值账户不存在");
        }
        UpdateWrapper<EntityXfAccountInfo> updateWrapper= new UpdateWrapper<>();
        updateWrapper.eq("com_id", companyId );
        updateWrapper.eq("p_id",pId);
        updateWrapper.setSql("account_recharge_money = account_recharge_money + " + money);
        updateWrapper.setSql("account_subsidy_money = account_subsidy_money + " + subMoney);

        updateWrapper.last("and 0 <= (account_recharge_money + " + money + ") and 0 <= (account_subsidy_money + " + subMoney + ")");

        Boolean b = this.update(updateWrapper);
        if(!b){
            throw new RuntimeException("充值失败");
        }
        EntityXfAccountInfo entityXfAccountInfo1 = this.getOne(queryWrapper);
        return entityXfAccountInfo1;
    }


    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyID",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityXfAccountInfo selectAccountNoBalance(Long companyID, String accountNo) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.select("p_id","account_recharge_money","account_subsidy_money");
        query.eq("com_id",companyID);
        query.eq("account_no",accountNo);
        query.eq("account_state",0);
        return iDaoAccountInfo.selectOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyID",isMaster = MasterSlaveEnum.SLAVE)
    @Override
    public EntityXfAccountInfo selectPIdBalance(Long companyID, Integer pId) {
        QueryWrapper<EntityXfAccountInfo> query = Wrappers.query();
        query.select("p_id","account_recharge_money","account_subsidy_money");
        query.eq("com_id",companyID);
        query.eq("p_id",pId);
        query.eq("account_state",0);
        return iDaoAccountInfo.selectOne(query);
    }

    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public boolean updateSign(Long companyId, Long pId, Integer signType, String signNo) {
        UpdateWrapper<EntityXfAccountInfo> update = Wrappers.update();
        update.eq("com_id",companyId);
        update.eq("p_id", pId);
        update.set("sign_type",signType);
        update.set("sign_no",signNo);
        return this.update(update);
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public boolean paraRefund(Long companyId,Integer accountId, Long orgId, EntityXfRecordProcess updateXfRecordProces, Integer refnudChargeBalance) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        updateWrapper.setSql("account_recharge_money = account_recharge_money + "+refnudChargeBalance);
        updateWrapper.eq("id",accountId);
        boolean up = this.update(updateWrapper);
        if(!up){
            return false;
        }
        if (xfRecordProcessService.updateEntityXfRecord(companyId,updateXfRecordProces)<=0){
            throw new RuntimeException("修改退款记录失败");
        }
        //更新原始为已退款
        if (!xfRecordProcessService.updateOrgEntityXfRecord(companyId,orgId)){
            throw new RuntimeException("修改原记录失败");
        }
        return  true;

    }


    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB,companyId = "companyId")
    public boolean paraRefundB(Long companyId,Integer accountId, Long orgId, EntityXfRecordProcess updateXfRecordProces, Integer refnudChargeBalance) {
        UpdateWrapper<EntityXfAccountInfo> updateWrapper=new UpdateWrapper<>();
        updateWrapper.setSql("account_recharge_money = account_recharge_money + "+refnudChargeBalance);
        updateWrapper.eq("id",accountId);
        boolean up = this.update(updateWrapper);
        if(!up){
            return false;
        }
        if (xfRecordProcessService.updateEntityXfRecord(companyId,updateXfRecordProces)<=0){
            throw new RuntimeException("修改退款记录失败");
        }
        //更新原始为已退款
        if (!xfRecordProcessService.updateOrgEntityXfRecordB(companyId,orgId)){
            throw new RuntimeException("修改原记录失败");
        }
        return  true;

    }


    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB)
    public void gzhRefundMoney(Long companyId, Integer id, EntityXfRecordProcess entityXfRecordProcess, EntityXfRecordProcess updateXfRecordProcess) {

        int i = xfRecordProcessService.insertEntityXfRecord(companyId, entityXfRecordProcess);
        if (i <= 0) {
            throw new RuntimeException("插入退款缓存表失败");
        }

        //修改原订单为已退款
        if (xfRecordProcessService.updateEntityXfRecord(companyId, updateXfRecordProcess) <= 0) {
            log.error("修改记录失败!订单号：{{}}", updateXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改原记录失败");
        }

        //修改金额
        UpdateWrapper<EntityXfAccountInfo> updateWrapper = new UpdateWrapper<>();
        if (entityXfRecordProcess.getChargeMoney() != null && entityXfRecordProcess.getChargeMoney() != 0) {
            updateWrapper.setSql("account_recharge_money = account_recharge_money - " + Math.abs(entityXfRecordProcess.getChargeMoney()));
        }
        if (entityXfRecordProcess.getSubMoney() != null && entityXfRecordProcess.getSubMoney() != 0) {
            updateWrapper.setSql("account_subsidy_money = account_subsidy_money - " + Math.abs(entityXfRecordProcess.getSubMoney()));
        }
        updateWrapper.eq("id", id);
        updateWrapper.eq("account_state", 0);
//       订单已退 必须成功
//        updateWrapper.last("and 0 <= (account_recharge_money - " + Math.abs(updateXfRecordProcess.getChargeMoney()) + ") and 0 <= (account_subsidy_money - " + Math.abs(updateXfRecordProcess.getSubMoney()) + ")");

        if (!this.update(updateWrapper)) {
            log.error("修改金额失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改金额失败");
        }



    }


    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB)
    public void gzhRefundOrderStatusSucc(Long companyId, EntityXfRecordProcess entityXfRecordProcess, EntityXfRecordProcess updateXfRecordProcess) {

        //修改原订单为已退款
        if (xfRecordProcessService.updateEntityXfRecord(companyId, entityXfRecordProcess) <= 0) {
            log.error("修改记录失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改原记录失败");
        }

        //修改退款缓存为成功
        if (xfRecordProcessService.updateEntityXfRecord(companyId, updateXfRecordProcess) <= 0) {
            log.error("修改记录失败!订单号：{{}}", updateXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改退款缓存记录失败");
        }

    }


    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    @DataSourceAspect(type = DataSourceEnum.PART_DB)
    public void gzhRefundOrderStatusFail(Long companyId, Integer id, EntityXfRecordProcess entityXfRecordProcess, EntityXfRecordProcess updateXfRecordProcess) {

        //修改金额
        UpdateWrapper<EntityXfAccountInfo> updateWrapper = new UpdateWrapper<>();
        if (entityXfRecordProcess.getChargeMoney() != null && entityXfRecordProcess.getChargeMoney() != 0) {
            updateWrapper.setSql("account_recharge_money = account_recharge_money + " + Math.abs(entityXfRecordProcess.getChargeMoney()));
        }
        if (entityXfRecordProcess.getSubMoney() != null && entityXfRecordProcess.getSubMoney() != 0) {
            updateWrapper.setSql("account_subsidy_money = account_subsidy_money + " + Math.abs(entityXfRecordProcess.getSubMoney()));
        }
        updateWrapper.eq("id", id);
        updateWrapper.eq("account_state", 0);
//       订单已退 必须成功
//        updateWrapper.last("and 0 <= (account_recharge_money - " + Math.abs(updateXfRecordProcess.getChargeMoney()) + ") and 0 <= (account_subsidy_money - " + Math.abs(updateXfRecordProcess.getSubMoney()) + ")");

        if (!this.update(updateWrapper)) {
            log.error("修改金额失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改金额失败");
        }

        //修改退款缓存为成功
        if (xfRecordProcessService.updateEntityXfRecord(companyId, entityXfRecordProcess) <= 0) {
            log.error("修改记录失败!订单号：{{}}", entityXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改退款缓存记录失败");
        }


        //修改原订单为已退款
        if (xfRecordProcessService.updateEntityXfRecord(companyId, updateXfRecordProcess) <= 0) {
            log.error("修改记录失败!订单号：{{}}", updateXfRecordProcess.getOrderNo());
            throw new RuntimeException("修改原记录失败");
        }
    }



}
